<!-- 游戏原包编辑弹窗 -->
<template>
  <el-dialog
    :title="isUpdate ? '修改游戏原包' : '添加游戏原包'"
    :visible="visible"
    width="1000px"
    :destroy-on-close="true"
    :lock-scroll="false"
    @update:visible="updateVisible"
    :close-on-click-modal="false"
  >
    <el-form ref="form" :model="form" :rules="rules" label-width="100px">
      <el-form-item
        v-if="this.isUpdate"
        label="选择游戏包:"
        prop="package_name"
        disabled
      >
        <el-input
          :maxlength="20"
          disabled
          v-model="form.package_name"
          placeholder="请选择游戏包"
          clearable
        />
      </el-form-item>
      <el-form-item
        v-else
        label="选择游戏包:"
        prop="package_name"
        filterable
        remote
        :remote-method="remoteMethod"
      >
        <PageSelect
          :placeholder="'请选择游戏包'"
          v-model="form.package_name"
          :whereName="'package_name'"
          :url="'/package/index'"
          :optionLable="'package_name'"
          :optionvalue="'id'"
          :multiple="false"
          @getAllOptioin="getAllOptioin"
        />
      </el-form-item>

      <el-form-item label="文件路径:" prop="file_url">
        <el-upload
          accept=".ipa,.apk,.zip,.exe"
          class="upload-demo"
          :action="uploadImgUrl"
          :on-preview="handlePreview"
          :on-remove="handleRemove"
          :before-remove="beforeRemove"
          multiple
          :limit="1"
          :headers="myHeaders"
          :on-exceed="handleExceed"
          :file-list="fileList"
          :http-request="uploadChunk"
        >
          <div>
            <el-button size="small" type="primary">点击上传</el-button>
            <div>文件上传（仅支持.ipa.apk.exe 和 .zip格式）</div>
          </div>
        </el-upload>
        <!-- 添加进度条 -->
        <el-progress v-if="showProgress" :percentage="uploadProgress" />
      </el-form-item>
      <el-form-item label="原包类型:" prop="file_type">
        <el-radio-group :disabled="this.file_disabled" v-model="form.file_type">
          <el-radio :label="1">安卓</el-radio>
          <el-radio :label="2">苹果</el-radio>
          <el-radio :label="3">h5</el-radio>
          <el-radio :label="4">pc</el-radio>
          <el-radio :label="5">小程序</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="数据单元:" prop="op_sys" v-if="form.file_type == 4">
        <el-radio-group v-model="form.op_sys">
          <el-radio :label="32">32位</el-radio>
          <el-radio :label="64">64位</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="备注:" prop="remark">
        <el-input v-model="form.remark" placeholder="请输入备注" clearable />
      </el-form-item>

      <el-form-item label="版本号:" prop="version">
        <el-input v-model="form.version" placeholder="请输入版本号" clearable />
      </el-form-item>

      <el-form-item label="原包包名:" prop="pack_name">
        <el-input
          v-model="form.pack_name"
          placeholder="请输入原包包名"
          clearable
        />
      </el-form-item>
    </el-form>
    <div slot="footer">
      <el-button @click="updateVisible(false)">取消</el-button>
      <el-button type="primary" @click="save" :loading="loading"
        >保存
      </el-button>
    </div>
  </el-dialog>
</template>

<script>
import setting from '@/config/setting'
import md5 from 'js-md5' //引入MD5加密
import PageSelect from '@/components/pageSelect/index.vue'

export default {
  name: 'GameSourceEdit',
  props: {
    // 弹窗是否打开
    visible: Boolean,
    // 修改回显的数据
    data: Object
  },
  components: { PageSelect },
  data() {
    let token = setting.takeToken()
    return {
      // 表单数据
      gameAll: [],
      fileList: [],
      sdk_version: '',
      package_Id: '',
      package_Name: '',
      uploadImgUrl: '',
      form: Object.assign({ op_sys: 32 }, this.data),
      myHeaders: { Authorization: token },
      // 表单验证规则
      rules: {
        game_id: [{ required: true, message: '请输入游戏id', trigger: 'blur' }],
        package_name: [
          { required: true, message: '请输入游戏包名称', trigger: 'blur' }
        ],
        file_name: [
          { required: true, message: '请输入文件名称', trigger: 'blur' }
        ],
        file_url: [{ required: true, message: '请上传文件', trigger: 'blur' }],
        file_size: [
          { required: true, message: '请输入文件大小', trigger: 'blur' }
        ],
        file_type: [
          {
            required: true,
            message: '请输入原包类型',
            trigger: 'blur'
          }
        ],
        plist_url: [
          { required: true, message: '请输入plist文件路径', trigger: 'blur' }
        ],
        op_admin_id: [
          { required: true, message: '请输入操作人id', trigger: 'blur' }
        ],
        op_admin_account: [
          { required: true, message: '请输入操作人名称', trigger: 'blur' }
        ],
        remark: [{ required: true, message: '请输入备注', trigger: 'blur' }],
        version: [{ required: true, message: '请输入版本号', trigger: 'blur' }],
        pack_name: [
          { required: true, message: '请输入原包包名', trigger: 'blur' }
        ],
        description_url: [
          { required: true, message: '请输入苹果描述文件url', trigger: 'blur' }
        ]
      },
      // 提交状态
      loading: false,
      // 是否是修改
      isUpdate: false,
      file_disabled: true,
      // 是否选中的游戏包为苹果
      isApple: false,
      currentChunk: 0, // 当前分片数
      showProgress: false, // 是否显示进度条
      uploadProgress: 0 // 上传进度
    }
  },
  watch: {
    data() {
      if (this.data) {
        this.form = Object.assign({ op_sys: 32 }, this.data)
        // console.log(this.form, "xiugai1");
        this.isUpdate = true
        this.showProgress = false
        this.uploadProgress = 0
      } else {
        this.form = Object.assign({ op_sys: 32 })
        this.showProgress = false
        this.uploadProgress = 0
        this.isUpdate = false
      }
    },
    'form.game_id'(val) {
      if (val) {
        this.gameAll.forEach((item) => {
          if (item.id == val) {
            // console.log("item", item);
            this.$set(this.form, 'file_type', item.sdk_version)
            this.$set(this.form, 'game_name', item.game_name)
          }
        })
      }
    },
    isApple(newV) {
      if (newV) {
        this.rules.pack_name = [
          { required: true, message: '请输入原包包名', trigger: 'blur' }
        ]
      } else {
        this.rules.pack_name = [
          { required: false, message: '请输入原包包名', trigger: 'blur' }
        ]
      }
    },
    fileList: {
      handler(val) {
        if (val.length) {
          this.$set(this.form, 'file_url', val[0].save_name)
          this.$set(this.form, 'file_size', val[0].file_size)
          this.$set(this.form, 'file_name', val[0].file_name)
        } else {
          this.$set(this.form, 'file_url', '')
          this.$set(this.form, 'file_size', '')
          this.$set(this.form, 'file_name', '')
        }
      },
      deep: true
    },
    'form.package_name'(newV, oldV) {
      if (newV != oldV) {
        // console.log("!!!", newV, oldV);
        if (newV != undefined) {
          // console.log("this.gameAll", this.gameAll);

          this.gameAll.forEach((item) => {
            // sdk_version和package_id

            if (item.id == newV) {
              // 渲染类型
              this.$set(this.form, 'file_type', item.sdk_version)
              // console.log(item, "item");
              this.sdk_version = item.sdk_version
              this.package_Id = item.id
              this.package_Name = item.package_name
              this.uploadImgUrl =
                process.env.VUE_APP_API_BASE_URL +
                '/upload/zoneUpload?sdk_version=' +
                this.sdk_version
              // console.log("sdk_version", this.sdk_version);
              // console.log("this.package_Id", this.package_Id);
              // console.log("this.package_Name", this.package_Name);
              // console.log("this.uploadImgUrl", this.uploadImgUrl);
              this.$set(this.form, 'package_name', this.package_Name)
              this.$set(this.form, 'package_id', this.package_Id)
              // console.log("this.fffffff", this.form);

              item.sdk_version == 2
                ? (this.isApple = true)
                : (this.isApple = false)
            }
          })
          this.file_disabled = true
        } else {
          // console.log("不可以选则");
          this.file_disabled = true
        }
      } else {
        // console.log("aaa");
        console.log('aaa', newV, oldV)
      }
    },
    'form.file_type'(val) {
      this.rules.pack_name =
        val == 2
          ? [{ required: true, message: '请输入原包包名', trigger: 'blur' }]
          : { required: false, message: '请输入原包包名', trigger: 'blur' }
    }
    // form(newVal, oldVal) {
    //   console.log("!!", newVal, "!!!", oldVal);
    //   // if (newVal.package_name !== ) {

    //   // }
    // }
  },
  methods: {
    getAllOptioin(arr) {
      this.gameAll = arr
    },
    handleRemove() {
      this.fileList = []
    },
    handlePreview(file) {
      console.log(file)
    },
    successUpload(response) {
      // this.$set(this.form, 'attach', response.data)
      console.log(response)
      // this.$set(this.fileList, this.fileList.length, {
      //   file_name: response.data.file_name,
      //   save_name: response.data.save_name,
      //   file_size: response.data.file_size,
      //   name: response.data.file_name
      // });
    },
    handleExceed() {
      this.$message.warning(`当前限制选择 1 个文件`)
    },
    async beforeRemove(file) {
      try {
        await this.$confirm(`确定移除 ${file.name}？`)
        // 用户点击确定后执行的代码
        this.showProgress = false
        this.uploadProgress = 0

        this.rules.file_url = [
          { required: true, message: '请上传文件', trigger: 'blur' }
        ]
        this.uploadChunk('false')
      } catch (error) {
        // 用户点击取消或关闭对话框时执行的代码，这里不需要做任何操作
      }
    },
    // 分片上传文件
    async uploadChunk(file) {
      // console.log(file, "file");
      if (file == 'false') {
        window.location.reload()
        return
      } else if (this.form.package_name == undefined) {
        // console.log(this.form.package_name);
        this.$message.error('请先选择游戏包')
        this.fileList = []
        return
      } else if (file == 'none') {
        return
      }
      const totalSize = file.file.size
      const totalSizeInMegabytes = totalSize / (1024 * 1024)
      // file_size
      const totalSizeInMegabytesFixed = totalSizeInMegabytes.toFixed(2) + 'MB'

      const chunkSize = 10 * 1024 * 1024 // 10MB
      const chunkCount = Math.ceil(totalSize / chunkSize)
      // console.log(
      //   chunkCount,
      //   "chunkCount",
      //   "totalSize",
      //   totalSizeInMegabytesFixed,
      //   "chunkSize",
      //   chunkSize
      // );

      // 显示进度条
      this.showProgress = true
      this.uploadProgress = 0
      const readChunkMD5 = async (chunk) => {
        return new Promise((resolve) => {
          let fileReaderInstance = new FileReader()
          fileReaderInstance.readAsBinaryString(chunk)
          fileReaderInstance.addEventListener('load', (e) => {
            let fileBlob = e.target.result
            let chunkMD5 = md5(fileBlob)
            resolve(chunkMD5)
          })
        })
      }

      const uploadChunkRecursive = async (index) => {
        if (index >= chunkCount) {
          return
        }
        // 更新当前分片数和总分片数
        this.currentChunk = index + 1

        const start = index * chunkSize
        const end = Math.min(start + chunkSize, totalSize)
        const chunk = file.file.slice(start, end)

        const chunkMD5 = await readChunkMD5(chunk)

        const formData = new FormData()
        const Sdk_version = this.isUpdate
          ? this.form.file_type
          : this.sdk_version
        formData.append('file', chunk)
        formData.append('chunkNumber', index + 1)
        formData.append('chunkSize', chunkSize)
        formData.append('currentChunkSize', chunk.size)
        formData.append('filename', file.file.name)
        formData.append('totalChunks', chunkCount)
        formData.append('md5', chunkMD5)
        // console.log("mmmmd", chunkMD5);

        try {
          const res = await this.$http.post(
            `/upload/zoneUpload?sdk_version=` + Sdk_version,
            formData
          )
          // console.log(res);
          if (res.data.code === 2) {
            this.rules.file_url = [
              { required: false, message: '请上传文件', trigger: 'blur' }
            ]
            this.uploadProgress = Math.round(
              (this.currentChunk / chunkCount) * 100
            )
            this.$set(this.form, 'file_url', res.data.file_path)
            this.$set(this.form, 'file_size', totalSizeInMegabytesFixed)
            this.$set(this.form, 'file_name', file.file.name)
            // console.log(this.form);
            this.$message.success(res.data.msg)
          } else if (res.data.code === 1) {
            this.uploadProgress = Math.round(
              (this.currentChunk / chunkCount) * 100
            )
            await uploadChunkRecursive(index + 1)
          } else if (res.data.code === -1) {
            this.$message.error(res.data.msg)
          }
        } catch (e) {
          this.loading = false
          this.$message.error(e.message)
        }
      }

      await uploadChunkRecursive(0)
    },
    /* 保存编辑 */
    save() {
      this.$refs['form'].validate((valid) => {
        if (valid) {
          this.loading = true
          if (!this.isUpdate) {
            this.form.package_id = this.package_Id
            this.form.package_name = this.package_Name
          }

          // console.log(this.form, "item");
          this.$http
            .post('/gamesource/edit', this.form)
            .then((res) => {
              this.loading = false
              if (res.data.code === 0) {
                this.$message.success(res.data.msg)
                if (!this.isUpdate) {
                  this.form = {}
                }
                this.rules.file_url = [
                  { required: true, message: '请上传文件', trigger: 'blur' }
                ]
                this.showProgress = false
                this.uploadProgress = 0
                this.updateVisible(false)
                this.$emit('done')
              } else {
                this.$confirm(res.data.msg, '提示', {
                  confirmButtonText: '确定',
                  type: 'warning'
                })
              }
            })
            .catch((e) => {
              this.loading = false
              this.$message.error(e.message)
            })
        } else {
          return false
        }
      })
    },
    /* 更新visible */
    updateVisible(value) {
      this.$emit('update:visible', value)
      // console.log(this.fileList, "fflst");
      if (this.showProgress) {
        this.uploadChunk('false')
      }
      this.showProgress = false
      this.uploadProgress = 0
    },
    // 是否更改了
    remoteMethod(query) {
      // console.log("！！！");
      if (query !== '') {
        this.loading = true
      } else {
        // console.log("！！!!！");
      }
    }
  }
}
</script>

<style scoped>
::v-deep .el-upload {
  text-align: left;
}
</style>
